/*
package com.schedule;

import com.Mapper.SecondaryMapper.SecondaryMapper;
import com.param.Engineer.*;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class EngineerSchedule {

    @Autowired
    private SecondaryMapper secondaryMapper;



    @XxlJob("engineeringLinkInfo")
    public void engineeringLinkInfo() throws Exception {

        List<EngineeringLinkInfo> infoList = secondaryMapper.getEngineeringLinkInfo();

      */
/*  List<EngineeringBaseInfo> baseInfo = secondaryMapper.getCityAndProJNumByEngBaseInfo();

        List<EngineeringLinkInfo> infoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(linkInfo)&&!CollectionUtils.isEmpty(baseInfo)){

            List<EngineeringLinkInfo> collect = linkInfo.stream().filter(x ->
                    baseInfo.stream().anyMatch(y -> StringUtils.equals(String.valueOf(x.getProjectId()), y.getId()))).collect(Collectors.toList());


            infoList = collect.stream().filter(s -> s.getSolutionID()!=0l && s.getLandID()!=0l

                    || s.getLandID()==0l && s.getSolutionID()!=0l).collect(Collectors.toList());
        }*//*


        List<EngineeringLinkInfo> oldLinkInfo = secondaryMapper.getExtractLinkInfo();

        List<EngineeringLinkInfo> copyLinkInfoList = new ArrayList<>(oldLinkInfo);
        copyLinkInfoList.removeAll(infoList);

        for (EngineeringLinkInfo info : copyLinkInfoList) {
            info.setState("0");
            secondaryMapper.updateLinkInfo(info);
        }

        infoList.removeAll(oldLinkInfo);
        if (!CollectionUtils.isEmpty(oldLinkInfo) && !CollectionUtils.isEmpty(infoList)) {
            Set<Long> itemIdList = oldLinkInfo.stream()
                    .map(EngineeringLinkInfo::getId)
                    .collect(Collectors.toSet());

            // 过滤
            List<EngineeringLinkInfo> updateList = infoList.stream()
                    .filter(s -> itemIdList.contains(s.getId()))
                    .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(updateList)) {
                for (EngineeringLinkInfo versions : updateList) {
                    secondaryMapper.updateLinkInfo(versions);
                }
            }
            infoList.removeAll(updateList);
        }
        if (!CollectionUtils.isEmpty(infoList)) {
            // 批次大小
            int batchSize = 100;

            // 计算需要多少个批次
            int totalBatches = (int) Math.ceil((double) infoList.size() / batchSize);

            for (int i = 0; i < totalBatches; i++) {
                // 计算当前批次的起始和结束索引
                int start = i * batchSize;
                int end = Math.min(start + batchSize, infoList.size());

                // 获取当前批次的数据
                List<EngineeringLinkInfo> subList = infoList.subList(start, end);

                // 执行当前批次的插入操作
                secondaryMapper.addExtractLinkInfo(subList);
            }
        }
    }

    @XxlJob("engineerPicInfo")
    public void engineerPicInfo() throws Exception {

        List<EngineeringBaseInfo> baseInfo = secondaryMapper.getCityAndProJNumByEngBaseInfo();

        //只取非 已完工的
        List<EngineeringBaseInfo> baseInfoList = baseInfo.stream().filter(s -> !StringUtils.equals(s.getProjectPhase(), "已完工")).collect(Collectors.toList());


        List<EngineeringPicInfo> picInfoList = secondaryMapper.getPicInfo();

        // List<EngineeringPicInfo> collectPersonList = new ArrayList<>();

        */
/*if (!CollectionUtils.isEmpty(baseInfoList)&&!CollectionUtils.isEmpty(picInfoList)){

            List<EngineeringBaseInfo> collect = baseInfoList.stream().filter(x ->
                    picInfoList.stream().anyMatch(y -> x.getId().equals(y.getProjectId()))).collect(Collectors.toList());

            //这里认为是人工录入的 ,保留.
            collectPersonList = baseInfoList.stream()
                    .flatMap(a -> picInfoList.stream()
                            .filter(b -> a.getId().equals(b.getProjectId()))
                            .map(b -> new EngineeringPicInfo(a.getId(), b.getProjectId(), "1", b.getFileType(), b.getFileName(), b.getFileCode())))
                    .collect(Collectors.toList());

            //此时baseInfo中剩余的 ,都认为是没有人工录入的 ,那么去project_version中找最新版本 ,拿到district_map =fileCode
            baseInfoList.removeAll(collect);
        }*//*



        List<ProjectVersions> version = secondaryMapper.getVersion();

        // 找出最新版
        Map<String, ProjectVersions> latestVersions = new HashMap<>();
        for (ProjectVersions versions : version) {
            String key = versions.getCity() + "_" + versions.getProjectNumber();
            if (!latestVersions.containsKey(key) ||
                    isNewerVersion(versions, latestVersions.get(key))) {
                latestVersions.put(key, versions);
            }
        }
        List<ProjectVersions> projectVersions = new ArrayList<>(latestVersions.values());


        List<ProjectVersions> filterList = projectVersions.stream().filter(s -> s.getDistrictMap()!=null
                &&s.getDistrictMap().length() >0).collect(Collectors.toList());

        //这里是从version表里找出的图片子表Engineering_PicInfo数据
        List<EngineeringPicInfo> collectVersionList = baseInfoList.stream()
                .flatMap(a -> filterList.stream()
                        .filter(b -> a.getCity().equals(b.getCity()) && a.getProjectNumber().equals(b.getProjectNumber()))
                        .map(b -> new EngineeringPicInfo(String.valueOf(100000000 + Integer.valueOf(a.getId())), a.getId(), "1", "工程项目图", "扫描图片.jpg", b.getDistrictMap())))
                .collect(Collectors.toList());

        //人工录入的+version提取的
        collectVersionList.addAll(picInfoList);

        List<EngineeringPicInfo> oldPicInfo = secondaryMapper.getExtractPicInfo();
        List<EngineeringPicInfo> copyPicInfoList = new ArrayList<>(oldPicInfo);
        copyPicInfoList.removeAll(collectVersionList);

        for (EngineeringPicInfo copy : copyPicInfoList) {
            copy.setState("0");
            secondaryMapper.updatePicInfo(copy);
        }

        collectVersionList.removeAll(oldPicInfo);


        if (!CollectionUtils.isEmpty(oldPicInfo) && !CollectionUtils.isEmpty(collectVersionList)) {

            Set<String> itemIdList = oldPicInfo.stream()
                    .map(EngineeringPicInfo::getId)
                    .collect(Collectors.toSet());

            // 过滤
            List<EngineeringPicInfo> updateList = collectVersionList.stream()
                    .filter(s -> itemIdList.contains(s.getId()))
                    .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(updateList)) {
                for (EngineeringPicInfo versions : updateList) {
                    secondaryMapper.updatePicInfo(versions);
                }
            }
            collectVersionList.removeAll(updateList);
        }
        if (!CollectionUtils.isEmpty(collectVersionList)) {
            // 批次大小
            int batchSize = 100;

            // 计算需要多少个批次
            int totalBatches = (int) Math.ceil((double) collectVersionList.size() / batchSize);

            for (int i = 0; i < totalBatches; i++) {
                // 计算当前批次的起始和结束索引
                int start = i * batchSize;
                int end = Math.min(start + batchSize, collectVersionList.size());

                // 获取当前批次的数据
                List<EngineeringPicInfo> subList = collectVersionList.subList(start, end);

                // 执行当前批次的插入操作
                secondaryMapper.addExtractPinInfo(subList);
            }
        }
    }

   @XxlJob("engineerDirectors")
   public void engineerDirectors() throws Exception {
       List<EngineeringDirectors> allProjectDirectors = secondaryMapper.getAllProjectDirectors();
       List<EngineeringDirectors> oldDirectors = secondaryMapper.getExtractDirectors();
       List<ExtractBaseInfo> baseInfo = secondaryMapper.getCityAndNumByExtractBaseInfo();
       List<ProjectVersions> version = secondaryMapper.getVersion();


       List<Directors> collect = baseInfo.stream()
               .flatMap(a -> version.stream()
                       .filter(b -> a.getCity().equals(b.getCity()) && a.getProjectNumber().equals(b.getProjectNumber()))
                       .map(b -> new Directors( a.getId(), b.getProjectID(), a.getCity(), a.getProjectNumber())))
               .collect(Collectors.toList());

       // 使用Map来根据City和ProjectNumber分组
       Map<String, List<Directors>> groupedList = collect.stream()
               .collect(Collectors.groupingBy(
                       s -> s.getCity() + ":" + s.getProjectNumber(), // 作为键的City:ProjectNumber字符串
                       Collectors.toList() // 收集具有相同键的用户到列表中
               ));





       List<EngineeringDirectors> directorList = new ArrayList<>();

       for (List<Directors> value : groupedList.values()) {
           List<EngineeringDirectors> newDirectors = value.stream()
                   .flatMap(a -> allProjectDirectors.stream()
                           .filter(b -> a.getProjectId().equals(b.getProjectId()))
                           .map(b -> new EngineeringDirectors(b.getItemID(), a.getProjectID(), b.getJobType(), b.getContractorUnit(), b.getEnterpriseNature()
                                   , b.getName(), b.getDepartment(), b.getPost(), b.getPhone(), b.getRegisterAddress(), b.getRemarks(),"1")))
                   .collect(Collectors.toList());

           //此时都在同一项目下,找出newDirectors 中重复的数据 ,去重
           if (newDirectors.size() > 1) {
               //为空时无法处理
           */
/*     Map<String, EngineeringDirectors> mergedDirectors = newDirectors.stream()
                        .collect(Collectors.toMap(
                                ed -> ed.getJobType() + "|" + ed.getContractorUnit() + "|" + ed.getName() + "|" + ed.getPhone(),
                                Function.identity(),
                                BinaryOperator.maxBy(Comparator.comparing(
                                        ed -> Arrays.asList(
                                                ed.getItemID(), ed.getEnterpriseNature(),
                                                ed.getDepartment(), ed.getPost(), ed.getRegisterAddress(), ed.getRemarks()
                                        ).stream()
                                                .map(String::toLowerCase) // 转换为小写以进行不区分大小写的比较
                                                .max(Comparator.naturalOrder())
                                                .orElse("") // 如果列表为空，则默认为空字符串
                                ))
                        ));*//*


               Map<String, List<EngineeringDirectors>> grouped = newDirectors.stream()
                       .collect(Collectors.groupingBy(
                               ed -> ed.getJobType() + "|" + ed.getContractorUnit() + "|" + ed.getName() + "|" + ed.getPhone()
                       ));

               Map<String, EngineeringDirectors> merged = new HashMap<>();

               for (Map.Entry<String, List<EngineeringDirectors>> entry : grouped.entrySet()) {
                   String key = entry.getKey();
                   List<EngineeringDirectors> group = entry.getValue();

                   // 假设第一个元素是有效的起点 ...任何起点都无所谓
                   EngineeringDirectors mergedEd = group.get(0);

                   // 遍历组中的其他元素来合并字段
                   for (int i = 1; i < group.size(); i++) {
                       EngineeringDirectors current = group.get(i);

                       // 这里只处理itemID和projectID作为示例
                       // 使用null-safe的比较和赋值
                       if (current.getItemID().compareTo(mergedEd.getItemID()) > 0) {
                           mergedEd.setItemID(current.getItemID());
                       }
                       if (current.getEnterpriseNature() != null && (mergedEd.getEnterpriseNature() == null || current.getEnterpriseNature().compareTo(mergedEd.getEnterpriseNature()) > 0)) {
                           mergedEd.setEnterpriseNature(current.getEnterpriseNature());
                       }

                       if (current.getDepartment() != null && (mergedEd.getDepartment() == null || current.getDepartment().compareTo(mergedEd.getDepartment()) > 0)) {
                           mergedEd.setDepartment(current.getDepartment());
                       }

                       if (current.getPost() != null && (mergedEd.getPost() == null || current.getPost().compareTo(mergedEd.getPost()) > 0)) {
                           mergedEd.setPost(current.getPost());
                       }

                       if (current.getRegisterAddress() != null && (mergedEd.getRegisterAddress() == null || current.getRegisterAddress().compareTo(mergedEd.getRegisterAddress()) > 0)) {
                           mergedEd.setRegisterAddress(current.getRegisterAddress());
                       }

                       if (current.getRemarks() != null && (mergedEd.getRemarks() == null || current.getRemarks().compareTo(mergedEd.getRemarks()) > 0)) {
                           mergedEd.setRemarks(current.getRemarks());
                       }
                       // 对其他字段重复上述逻辑
                   }

                   merged.put(key, mergedEd);
               }
               List<EngineeringDirectors> filteredList = new ArrayList<>(merged.values());
               directorList.addAll(filteredList);
           } else  if (newDirectors.size()==1){
               directorList.addAll(newDirectors);
           }
       }
       //Collections.sort(directorList, (u1, u2) -> Integer.compare(Integer.valueOf(u1.getItemID()), Integer.valueOf(u2.getItemID())));

       ArrayList<EngineeringDirectors> copyDirectors = new ArrayList<>(oldDirectors);
       copyDirectors.removeAll(directorList);
       for (EngineeringDirectors copyDirector : copyDirectors) {
           copyDirector.setState("0");
           secondaryMapper.updateDirectors(copyDirector);
       }

       directorList.removeAll(oldDirectors);
       //使用Set  ,避免双重遍历
       if (!CollectionUtils.isEmpty(oldDirectors) && !CollectionUtils.isEmpty(directorList)) {

           Set<String> itemIdList = oldDirectors.stream()
                   .map(EngineeringDirectors::getItemID)
                   .collect(Collectors.toSet());

           // 过滤
           List<EngineeringDirectors> updateList = directorList.stream()
                   .filter(s -> itemIdList.contains(s.getItemID()))
                   .collect(Collectors.toList());

           if (!CollectionUtils.isEmpty(updateList)) {
               for (EngineeringDirectors versions : updateList) {
                   secondaryMapper.updateDirectors(versions);
               }
           }
           directorList.removeAll(updateList);
       }


       //去除重复的 ,剩下的认为是需要新增
       //     directorList.removeAll(oldDirectors);
       if (!CollectionUtils.isEmpty(directorList)) {
           // 批次大小
           int batchSize = 100;

           // 计算需要多少个批次
           int totalBatches = (int) Math.ceil((double) directorList.size() / batchSize);

           for (int i = 0; i < totalBatches; i++) {
               // 计算当前批次的起始和结束索引
               int start = i * batchSize;
               int end = Math.min(start + batchSize, directorList.size());

               // 获取当前批次的数据
               List<EngineeringDirectors> subList = directorList.subList(start, end);

               // 执行当前批次的插入操作
               secondaryMapper.addExtractDirectorList(subList);
           }
       }

   }

    @XxlJob("engineerVersion")
    public void engineerVersion() throws Exception {

        // List<EngineeringBaseInfo> baseInfoList = secondaryMapper.getCityAndProJNumByEngBaseInfo();
        List<ExtractBaseInfo> baseInfoList = secondaryMapper.getCityAndNumByExtractBaseInfo();

        List<ExtractEngineeringVersions> versionsList = secondaryMapper.getEngineeringVersions();

        //在     versionsList 中取出和  baseInfoList中city和num相等的数据 ,并且调整 baseInfoList 的id

        List<ExtractEngineeringVersions> matchingVersions = new ArrayList<>();
        if (!CollectionUtils.isEmpty(versionsList)) {
            for (ExtractBaseInfo baseInfo : baseInfoList) {
                //考虑使用stream流 ,但是使用流无法处理字段为null的情况 ,所以使用for遍历
                for (ExtractEngineeringVersions versions : versionsList) {
                    if (versions.getCity() != null && versions.getCity().equals(baseInfo.getCity())
                            && versions.getProjectNumber() != null && versions.getProjectNumber().equals(baseInfo.getProjectNumber())) {
                        versions.setCity(null);
                        versions.setProjectNumber(null);
                        versions.setProjectID(baseInfo.getId());
                        matchingVersions.add(versions);
                    }
                }
             */
/*   matchingVersions = versionsList.stream()
                        .filter(s -> s.getCity().equals(baseInfo.getCity()) && s.getProjectNumber().equals(baseInfo.getProjectNumber()))
                      //  .peek(s->s.setProjectNumber(baseInfo.getProjectNumber()))
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(matchingVersions)){
                    matchingVersions.forEach(s -> {
                        s.setProjectID(baseInfo.getId());
                        s.setProjectNumber(null);
                        s.setCity(null); //这里改变了对象 ,City和number给值null ,下次循环时会报错 ,无法处理
                    });
                }*//*


            }

        }
        if (!CollectionUtils.isEmpty(matchingVersions)) {
            List<ExtractEngineeringVersions> oldExtractEngineeringVersions = secondaryMapper.getExtractEngineeringVersions();

            List<ExtractEngineeringVersions> copiedList = new ArrayList<>(oldExtractEngineeringVersions);


            //剩余的是 version表里删除了 ,但是ExtractEngineeringVersions 表里还在的数据 ,也应该state=0 (有一部分是更新操作,这里把state置0 ,下面逻辑代码会改回)
            copiedList.removeAll(matchingVersions);
            if (!CollectionUtils.isEmpty(copiedList)) {

                for (ExtractEngineeringVersions oldExtractEngineeringVersion : copiedList) {
                    oldExtractEngineeringVersion.setState("0");
                    secondaryMapper.updateExtractVersionList(oldExtractEngineeringVersion);
                }
            }


            //去除掉重复元素.

            matchingVersions.removeAll(oldExtractEngineeringVersions);

            //查找 matchingVersions  和oldExtractEngineeringVersions 中 , item相同的数据 ,
            // 这批数据,认为是需要update的  (考虑project_version表可能会认为的update ,所以extract_engineering_versions也同步更新)

            //使用Set  ,避免双重遍历
            if (!CollectionUtils.isEmpty(oldExtractEngineeringVersions) && !CollectionUtils.isEmpty(matchingVersions)) {

                Set<String> itemIdList = oldExtractEngineeringVersions.stream()
                        .map(ExtractEngineeringVersions::getItemID)
                        .collect(Collectors.toSet());

                // 过滤
                List<ExtractEngineeringVersions> updateList = matchingVersions.stream()
                        .filter(s -> itemIdList.contains(s.getItemID()))
                        .collect(Collectors.toList());

                //理论上数据极少 ,所以不考虑效率 .实际上考虑效率可能也用for+sql .
                if (!CollectionUtils.isEmpty(updateList)) {
                    for (ExtractEngineeringVersions versions : updateList) {
                        secondaryMapper.updateExtractVersionList(versions);
                    }
                }

                //此时剩余的数据 认为是需要新增.
                matchingVersions.removeAll(updateList);


            }
        }

      */
/*  //考虑情况 :project_versions表中 city从北京变成天津 ,上面逻辑无法处理 ,故添加
        List<String> idList = secondaryMapper.selectExtractVersionId();

        List<ExtractEngineeringVersions> filteredList = matchingVersions.stream()
                .filter(s -> idList.contains(s.getItemID()))
                .collect(Collectors.toList());
        for (ExtractEngineeringVersions versions : filteredList) {
            secondaryMapper.updateExtractVersionList(versions);
        }

        matchingVersions.removeAll(filteredList);*//*


        if (!CollectionUtils.isEmpty(matchingVersions)) {
            // 批次大小
            int batchSize = 100;

            // 计算需要多少个批次
            int totalBatches = (int) Math.ceil((double) matchingVersions.size() / batchSize);

            for (int i = 0; i < totalBatches; i++) {
                // 计算当前批次的起始和结束索引
                int start = i * batchSize;
                int end = Math.min(start + batchSize, matchingVersions.size());

                // 获取当前批次的数据
                List<ExtractEngineeringVersions> subList = matchingVersions.subList(start, end);

                // 执行当前批次的插入操作
                secondaryMapper.addExtractVersionList(subList);
            }
        }

    }


    */
/**
     * 工程项目表处理逻辑
     *
     * @throws Exception
     *//*

    @XxlJob("engineerBaseInfo")
    public void engineerBaseInfo() throws Exception {
        List<ProjectVersions> versionsList = secondaryMapper.selectVersion();

        // 使用Map来存储每个项目的最新版本，key为唯一标识（城市+项目编号）
        Map<String, ProjectVersions> latestVersions = new HashMap<>();

        for (ProjectVersions versions : versionsList) {
            String key = versions.getCity() + "_" + versions.getProjectNumber();

            if (!latestVersions.containsKey(key) ||
                    isNewerVersion(versions, latestVersions.get(key))) {
                latestVersions.put(key, versions);
            }
        }

        //原始扫描数据 ,放入Map
        List<ProjectVersions> projectVersions = new ArrayList<>(latestVersions.values());
        Map<String, ProjectVersions> versionList = projectVersions.stream()
                .collect(Collectors.toMap(ProjectVersions::getItemID, Function.identity()));

        //人工录入数据
        List<EngineeringBaseInfo> basePerson = secondaryMapper.selectEngineeringBaseInfo();

        List<EngineeringBaseInfo> completeList = basePerson.stream().filter(s -> StringUtils.equals(s.getProjectPhase(), "已完工")).collect(Collectors.toList());

        List<ExtractBaseInfo> extractList = new ArrayList<>();
        for (EngineeringBaseInfo baseInfo : completeList) {
            ExtractBaseInfo extractBaseInfo = new ExtractBaseInfo();
            BeanUtils.copyProperties(baseInfo,extractBaseInfo);
            extractList.add(extractBaseInfo);
        }

        //剩下的都是未完工的 ,去version表取数据 ,以version表为主
        basePerson.removeAll(completeList);


        //获取全部的应用表数据
        List<ExtractBaseInfo> oldExtract = secondaryMapper.selectExtractAll();
        //复制一份
        List<ExtractBaseInfo> copiedList = new ArrayList<>(oldExtract);


        //遍历人工录入数据 ,查找人工和原始数据重复部分取值.
        for (EngineeringBaseInfo person : basePerson) {

            if (versionList.containsKey(person.getVersionItemID())) {
                ProjectVersions versions = versionList.get(person.getVersionItemID());
                //获得拼合数据
                ExtractBaseInfo extract = new ExtractBaseInfo();
                BeanUtils.copyProperties(versions,extract);
                extract.setCity(person.getCity());
                extract.setId(person.getId());
                extract.setProjectNumber(person.getProjectNumber());
                extract.setReleaseTime(person.getReleaseTime());
                extractList.add(extract);
            }else {
                ExtractBaseInfo baseInfo = new ExtractBaseInfo();
                baseInfo.setState("1");
                baseInfo.setId(person.getId());
                baseInfo.setCity(person.getCity());
                baseInfo.setProjectNumber(person.getProjectNumber());
                baseInfo.setReleaseTime(person.getReleaseTime());
                extractList.add(baseInfo);
            }
        }

        //extractList 中数据已经被整理 ,但也需要考虑和应用表数据重复问题 .

        //extractList  和oldExtract中 ,找出相同的项目 ,认为这些项目 1 :可能并没有发生变动 ,无需处理 2: 可能需要update
        List<ExtractBaseInfo> updateExtractList = extractList.stream()
                .filter(x -> oldExtract.stream().anyMatch(y ->
                        x.getCity().equals(y.getCity()) &&
                                x.getProjectNumber().equals(y.getProjectNumber())))
                .collect(Collectors.toList());


        //这批数据认为库里已有的,比现在查出来的多了 (认为是删除了 ,或者是更新了,这里统一置0,被误操作的更新的数据,下面逻辑代码会还原)
        copiedList.removeAll(updateExtractList);
        //TODO 这一步考虑可有可无 ,没时间验证
        if (!CollectionUtils.isEmpty(copiedList)) {
            for (ExtractBaseInfo extractBaseInfo : copiedList) {
                extractBaseInfo.setState("0");//TODO  这里应该物理删除逻辑更友好,节省资源
                secondaryMapper.updateExtractList(extractBaseInfo);
            }
        }

        updateExtractList.removeAll(oldExtract);
        if (!CollectionUtils.isEmpty(updateExtractList)) {
            for (ExtractBaseInfo extractBaseInfo : updateExtractList) {
                secondaryMapper.updateExtractList(extractBaseInfo);
            }
        }

       */
/* //此时判断updateExtractList数据中 ,哪些变动哪些没变动 . 将updateExtractList 和 oldExtract 进行比较
        Map<String, ExtractBaseInfo> oldExtractById = oldExtract.stream().collect(Collectors.toMap(ExtractBaseInfo::getId, oE -> oE));

        // 新建一个列表来存储有差异的对象
        List<ExtractBaseInfo> differingEntries = new ArrayList<>();

        for (ExtractBaseInfo baseInfo : updateExtractList) {
            ExtractBaseInfo correspondingInfo = oldExtractById.get(baseInfo.getId());
            // 检查是否存在对应项且除updateTime外有不匹配的字段
            if (correspondingInfo != null && !isMatchingExceptUpdateTime(baseInfo, correspondingInfo)) {
                differingEntries.add(baseInfo);
            }
        }
        for (ExtractBaseInfo extractBaseInfo : differingEntries) {

            secondaryMapper.updateExtractList(extractBaseInfo);
        }*//*

        //认为去除了需要更新的extractList ,剩下的数据需要插入.
        extractList.removeAll(oldExtract); //去除了相同的
        extractList.removeAll(updateExtractList); //去除了刚刚更新的 ,认为剩下的是需要新增的


        // 创建一个集合来存储需要从extractList中删除的元素
        List<ExtractBaseInfo> toRemove = new ArrayList<>();

        // 遍历extractList，检查是否需要删除元素
        if (!CollectionUtils.isEmpty(extractList)) {
            for (ExtractBaseInfo extractBaseInfo : extractList) {
                for (ExtractBaseInfo baseInfo : copiedList) {
                    if (StringUtils.equals(baseInfo.getId(), extractBaseInfo.getId())) { // 注意这里使用equals而不是hashCode
                        secondaryMapper.updateExtractList(extractBaseInfo);
                        toRemove.add(extractBaseInfo); // 标记需要删除的元素
                        break; // 找到匹配项后，跳出内层循环
                    }
                }
            }
            // 遍历toRemove列表，并从extractList中删除这些元素
            extractList.removeAll(toRemove);
        }
        //TODO  这部分数据暂时不考虑
        //versionList中剩余数据认为没有被人工录入过 ,使用原始数据 .但使用原始数据插入应用表 ,也需要考虑重复问题 (版本变动问题)
       */
/* List<ProjectVersions> noPersonVersions = new ArrayList<>(versionList.values());
        List<ExtractBaseInfo> noPersonVersionList = new ArrayList<>();
        List<ExtractBaseInfo> updateNoPeopleExtractList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(noPersonVersions)) {

            //复制属性 ,方便下一步比较取值
            for (ProjectVersions noPersonVersion : noPersonVersions) {
                ExtractBaseInfo extractBaseInfo = new ExtractBaseInfo();
                BeanUtils.copyProperties(noPersonVersion, extractBaseInfo);
                noPersonVersionList.add(extractBaseInfo);
            }
            //noPersonVersionList  和oldExtract中 ,找出相同的项目 ,认为这些项目需要更新而不是 插入
            updateNoPeopleExtractList = noPersonVersionList.stream()
                    .filter(x -> oldExtract.stream().anyMatch(y ->
                            x.getCity().equals(y.getCity()) &&
                                    x.getProjectNumber().equals(y.getProjectNumber())))
                    .collect(Collectors.toList());
        }

        //认为去除了需要更新的extractList ,剩下的数据需要插入.
        noPersonVersionList.removeAll(updateNoPeopleExtractList);*//*


        //插入
        // noPersonVersionList.addAll(extractList); //TODO
        // if (!CollectionUtils.isEmpty(noPersonVersionList)) {
        //暂时不考虑 : versions表中有数据 ,但是人工录入表里没有数据的 情况 .这批数据 ,即便是满足要求,也暂时不入库
        if (!CollectionUtils.isEmpty(extractList)) {
            // 批次大小
            int batchSize = 100;

            // 计算需要多少个批次
            int totalBatches = (int) Math.ceil((double) extractList.size() / batchSize);

            for (int i = 0; i < totalBatches; i++) {
                // 计算当前批次的起始和结束索引
                int start = i * batchSize;
                int end = Math.min(start + batchSize, extractList.size());

                // 获取当前批次的数据
                List<ExtractBaseInfo> subList = extractList.subList(start, end);

                // 执行当前批次的插入操作
                secondaryMapper.insertExtractList(subList);

                // 根据需要，这里可以添加日志或休息一小段时间以避免过于频繁的数据库操作
                // System.out.println("Inserted batch " + (i + 1) + " of " + totalBatches);
                // Try to sleep for a short duration between batches to avoid overwhelming the database
                // try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
            }
            // secondaryMapper.insertExtractList(noPersonVersionList);
        }

        //更新
        */
/*updateNoPeopleExtractList.addAll(updateExtractList);
        if (!CollectionUtils.isEmpty(updateNoPeopleExtractList)) {
            //更新sql
        }*//*



    }

    private boolean isMatchingExceptUpdateTime(ExtractBaseInfo baseInfo, ExtractBaseInfo correspondingInfo) {
        return Objects.equals(baseInfo.getState(), correspondingInfo.getState()) // 状态
                && Objects.equals(baseInfo.getReleaseTime(), correspondingInfo.getReleaseTime()) // 发布时间
                && Objects.equals(baseInfo.getCity(), correspondingInfo.getCity()) // 城市
                && Objects.equals(baseInfo.getRegion(), correspondingInfo.getRegion()) // 区域
                && Objects.equals(baseInfo.getProjectCaption(), correspondingInfo.getProjectCaption()) // 项目标题
                && Objects.equals(baseInfo.getProjectNumber(), correspondingInfo.getProjectNumber()) // 项目编号
                && Objects.equals(baseInfo.getTags(), correspondingInfo.getTags()) // 标签
                && Objects.equals(baseInfo.getProjectPhase(), correspondingInfo.getProjectPhase()) // 项目阶段
                && Objects.equals(baseInfo.getIndustry(), correspondingInfo.getIndustry()) // 行业
                && Objects.equals(baseInfo.getIndustryLevel(), correspondingInfo.getIndustryLevel()) // 行业级别
                && Objects.equals(baseInfo.getBelongIndustry(), correspondingInfo.getBelongIndustry()) // 所属行业
                && Objects.equals(baseInfo.getDetailedAddress(), correspondingInfo.getDetailedAddress()) // 详细地址
                && Objects.equals(baseInfo.getBuildArea(), correspondingInfo.getBuildArea()) // 建筑面积
                && Objects.equals(baseInfo.getBuildAreaA(), correspondingInfo.getBuildAreaA()) // 建筑面积A
                && Objects.equals(baseInfo.getBuildAreaU(), correspondingInfo.getBuildAreaU()) // 建筑面积U
                && Objects.equals(baseInfo.getBuildFloor(), correspondingInfo.getBuildFloor()) // 建筑楼层
                && Objects.equals(baseInfo.getFloorNum(), correspondingInfo.getFloorNum()) // 楼层数
                && Objects.equals(baseInfo.getEngineeringType(), correspondingInfo.getEngineeringType()) // 工程类型
                && Objects.equals(baseInfo.getConstructionCycle(), correspondingInfo.getConstructionCycle()) // 施工周期
                && Objects.equals(baseInfo.getInvestmentAmount(), correspondingInfo.getInvestmentAmount()) // 投资金额
                && Objects.equals(baseInfo.getOccupyArea(), correspondingInfo.getOccupyArea()) // 占地面积
                && Objects.equals(baseInfo.getTopic(), correspondingInfo.getTopic()) // 主题
                && Objects.equals(baseInfo.getProjectScale(), correspondingInfo.getProjectScale()) // 项目规模
                && Objects.equals(baseInfo.getQuantityScale(), correspondingInfo.getQuantityScale()) // 数量规模
                && Objects.equals(baseInfo.getSetTotal(), correspondingInfo.getSetTotal()) // 总套数
                && Objects.equals(baseInfo.getPartyAType(), correspondingInfo.getPartyAType()) // 甲方类型
                && Objects.equals(baseInfo.getForeignCapital(), correspondingInfo.getForeignCapital()) // 外资情况
                && Objects.equals(baseInfo.getHasDecoration(), correspondingInfo.getHasDecoration()) // 是否装修
                && Objects.equals(baseInfo.getDecoration(), correspondingInfo.getDecoration()) // 装修情况
                && Objects.equals(baseInfo.getDecorationRemark(), correspondingInfo.getDecorationRemark()) // 装修备注
                && Objects.equals(baseInfo.getSteelStructure(), correspondingInfo.getSteelStructure()) // 钢结构
                && Objects.equals(baseInfo.getExternalWallMaterials(), correspondingInfo.getExternalWallMaterials()) // 外墙材料
                && Objects.equals(baseInfo.getHasPark(), correspondingInfo.getHasPark()) // 是否有停车场
                && Objects.equals(baseInfo.getPark(), correspondingInfo.getPark()) // 停车场信息
                && Objects.equals(baseInfo.getParkRemark(), correspondingInfo.getParkRemark()) // 停车场备注
                && Objects.equals(baseInfo.getHasAirConditioning(), correspondingInfo.getHasAirConditioning()) // 是否有空调
                && Objects.equals(baseInfo.getAirConditioning(), correspondingInfo.getAirConditioning()) // 空调情况
                && Objects.equals(baseInfo.getAirConditioningRemark(), correspondingInfo.getAirConditioningRemark()) // 空调备注
                && Objects.equals(baseInfo.getElevator(), correspondingInfo.getElevator()) // 电梯
                && Objects.equals(baseInfo.getFreshAirSystem(), correspondingInfo.getFreshAirSystem()) // 新风系统
                && Objects.equals(baseInfo.getHasHeating(), correspondingInfo.getHasHeating()) // 是否有供暖
                && Objects.equals(baseInfo.getHeatingMethod(), correspondingInfo.getHeatingMethod()) // 供暖方式
                && Objects.equals(baseInfo.getHeatingRemark(), correspondingInfo.getHeatingRemark()) // 供暖备注
                && Objects.equals(baseInfo.getPrefabricatedBuildings(), correspondingInfo.getPrefabricatedBuildings()) // 装配式建筑
                && Objects.equals(baseInfo.getPassiveRoom(), correspondingInfo.getPassiveRoom()) // 被动房
                && Objects.equals(baseInfo.getBuildInfo(), correspondingInfo.getBuildInfo()) // 建筑信息
                && Objects.equals(baseInfo.getProjectEquipment(), correspondingInfo.getProjectEquipment()) // 项目设备
                && Objects.equals(baseInfo.getProjectProgress(), correspondingInfo.getProjectProgress()) // 项目进度
                && Objects.equals(baseInfo.getLng(), correspondingInfo.getLng()) // 经度
                && Objects.equals(baseInfo.getLat(), correspondingInfo.getLat()) // 纬度
                && Objects.equals(baseInfo.getGaoDeLng(), correspondingInfo.getGaoDeLng()) // 高德经度
                && Objects.equals(baseInfo.getGaoDeLat(), correspondingInfo.getGaoDeLat()) // 高德纬度
                && Objects.equals(baseInfo.getSteelStructureRemark(), correspondingInfo.getSteelStructureRemark()) // 钢结构备注
                && Objects.equals(baseInfo.getOtherExternalWallMaterials(), correspondingInfo.getOtherExternalWallMaterials()) // 其他外墙材料
                && Objects.equals(baseInfo.getExternalWallMaterialsRemark(), correspondingInfo.getExternalWallMaterialsRemark()) // 外墙材料备注
                && Objects.equals(baseInfo.getElevatorRemark(), correspondingInfo.getElevatorRemark()) // 电梯备注
                && Objects.equals(baseInfo.getFreshAirSystemRemark(), correspondingInfo.getFreshAirSystemRemark()) // 新风系统备注
                && Objects.equals(baseInfo.getOtherHeatingMethod(), correspondingInfo.getOtherHeatingMethod()) // 其他供暖方式
                && Objects.equals(baseInfo.getVersion(), correspondingInfo.getVersion()); // 版本
    }


    private ExtractBaseInfo copyProperty(ProjectVersions versions, EngineeringBaseInfo person) {
        ExtractBaseInfo extract = new ExtractBaseInfo();
        extract.setId(person.getId());
        extract.setReleaseTime(versions.getReleaseTime());
        extract.setVersion(person.getVersion());
        extract.setCity(person.getCity());
        extract.setState("1");

        if (!StringUtils.isEmpty(person.getRegion())) {
            extract.setRegion(person.getRegion());
        } else {
            extract.setRegion(versions.getRegion());
        }

        if (!StringUtils.isEmpty(person.getProjectCaption())) {
            extract.setProjectCaption(person.getProjectCaption());
        } else {
            extract.setProjectCaption(versions.getProjectCaption());
        }

        if (!StringUtils.isEmpty(person.getProjectNumber())) {
            extract.setProjectNumber(person.getProjectNumber());
        } else {
            extract.setProjectNumber(versions.getProjectNumber());
        }

        if (!StringUtils.isEmpty(person.getTags())) {
            extract.setTags(person.getTags());
        } else {
            extract.setTags(versions.getTags());
        }

        if (!StringUtils.isEmpty(person.getProjectPhase())) {
            extract.setProjectPhase(person.getProjectPhase());
        } else {
            extract.setProjectPhase(versions.getProjectPhase());
        }

        if (!StringUtils.isEmpty(person.getIndustry())) {
            extract.setIndustry(person.getIndustry());
        } else {
            extract.setIndustry(versions.getIndustry());
        }

        if (!StringUtils.isEmpty(person.getIndustryLevel())) {
            extract.setIndustryLevel(person.getIndustryLevel());
        } else {
            extract.setIndustryLevel(versions.getIndustryLevel());
        }

        if (!StringUtils.isEmpty(person.getBelongIndustry())) {
            extract.setBelongIndustry(person.getBelongIndustry());
        } else {
            extract.setBelongIndustry(versions.getBelongIndustry());
        }

        if (!StringUtils.isEmpty(person.getDetailedAddress())) {
            extract.setDetailedAddress(person.getDetailedAddress());
        } else {
            extract.setDetailedAddress(versions.getDetailedAddress());
        }

        if (!StringUtils.isEmpty(person.getBuildArea())) {
            extract.setBuildArea(person.getBuildArea());
        } else {
            extract.setBuildArea(versions.getBuildArea());
        }

        if (!StringUtils.isEmpty(person.getBuildAreaA())) {
            extract.setBuildAreaA(person.getBuildAreaA());
        } else {
            extract.setBuildAreaA(versions.getBuildAreaA());
        }

        if (!StringUtils.isEmpty(person.getBuildAreaU())) {
            extract.setBuildAreaU(person.getBuildAreaU());
        } else {
            extract.setBuildAreaU(versions.getBuildAreaU());
        }

        if (!StringUtils.isEmpty(person.getBuildFloor())) {
            extract.setBuildFloor(person.getBuildFloor());
        } else {
            extract.setBuildFloor(versions.getBuildFloor());
        }

        if (!StringUtils.isEmpty(person.getFloorNum())) {
            extract.setFloorNum(person.getFloorNum());
        } else {
            extract.setFloorNum(versions.getFloorNum());
        }

        if (!StringUtils.isEmpty(person.getEngineeringType())) {
            extract.setEngineeringType(person.getEngineeringType());
        } else {
            extract.setEngineeringType(versions.getEngineeringType());
        }

        if (!StringUtils.isEmpty(person.getConstructionCycle())) {
            extract.setConstructionCycle(person.getConstructionCycle());
        } else {
            extract.setConstructionCycle(versions.getConstructionCycle());
        }

        if (!StringUtils.isEmpty(person.getInvestmentAmount())) {
            extract.setInvestmentAmount(person.getInvestmentAmount());
        } else {
            extract.setInvestmentAmount(versions.getInvestmentAmount());
        }

        if (!StringUtils.isEmpty(person.getOccupyArea())) {
            extract.setOccupyArea(person.getOccupyArea());
        } else {
            extract.setOccupyArea(versions.getOccupyArea());
        }

        if (!StringUtils.isEmpty(person.getTopic())) {
            extract.setTopic(person.getTopic());
        } else {
            extract.setTopic(versions.getTopic());
        }

        if (!StringUtils.isEmpty(person.getProjectScale())) {
            extract.setProjectScale(person.getProjectScale());
        } else {
            extract.setProjectScale(versions.getProjectScale());
        }

        if (!StringUtils.isEmpty(person.getQuantityScale())) {
            extract.setQuantityScale(person.getQuantityScale());
        } else {
            extract.setQuantityScale(versions.getQuantityScale());
        }

        if (!StringUtils.isEmpty(person.getSetTotal())) {
            extract.setSetTotal(person.getSetTotal());
        } else {
            extract.setSetTotal(versions.getSetTotal());
        }

        if (!StringUtils.isEmpty(person.getPartyAType())) {
            extract.setPartyAType(person.getPartyAType());
        } else {
            extract.setPartyAType(versions.getPartyAType());
        }

        if (!StringUtils.isEmpty(person.getForeignCapital())) {
            extract.setForeignCapital(person.getForeignCapital());
        } else {
            extract.setForeignCapital(versions.getForeignCapital());
        }

        if (!StringUtils.isEmpty(person.getHasDecoration())) {
            extract.setHasDecoration(person.getHasDecoration());
        } else {
            extract.setHasDecoration(versions.getHasDecoration());
        }

        if (!StringUtils.isEmpty(person.getDecoration())) {
            extract.setDecoration(person.getDecoration());
        } else {
            extract.setDecoration(versions.getDecoration());
        }

        if (!StringUtils.isEmpty(person.getDecorationRemark())) {
            extract.setDecorationRemark(person.getDecorationRemark());
        } else {
            extract.setDecorationRemark(versions.getDecorationRemark());
        }

        if (!StringUtils.isEmpty(person.getSteelStructure())) {
            extract.setSteelStructure(person.getSteelStructure());
        } else {
            extract.setSteelStructure(versions.getSteelStructure());
        }

        if (!StringUtils.isEmpty(person.getExternalWallMaterials())) {
            extract.setExternalWallMaterials(person.getExternalWallMaterials());
        } else {
            extract.setExternalWallMaterials(versions.getExternalWallMaterials());
        }

        if (!StringUtils.isEmpty(person.getHasPark())) {
            extract.setHasPark(person.getHasPark());
        } else {
            extract.setHasPark(versions.getHasPark());
        }

        if (!StringUtils.isEmpty(person.getPark())) {
            extract.setPark(person.getPark());
        } else {
            extract.setPark(versions.getPark());
        }

        if (!StringUtils.isEmpty(person.getParkRemark())) {
            extract.setParkRemark(person.getParkRemark());
        } else {
            extract.setParkRemark(versions.getParkRemark());
        }

        if (!StringUtils.isEmpty(person.getHasAirConditioning())) {
            extract.setHasAirConditioning(person.getHasAirConditioning());
        } else {
            extract.setHasAirConditioning(versions.getHasAirConditioning());
        }

        if (!StringUtils.isEmpty(person.getAirConditioning())) {
            extract.setAirConditioning(person.getAirConditioning());
        } else {
            extract.setAirConditioning(versions.getAirConditioning());
        }

        if (!StringUtils.isEmpty(person.getAirConditioningRemark())) {
            extract.setAirConditioningRemark(person.getAirConditioningRemark());
        } else {
            extract.setAirConditioningRemark(versions.getAirConditioningRemark());
        }

        if (!StringUtils.isEmpty(person.getElevator())) {
            extract.setElevator(person.getElevator());
        } else {
            extract.setElevator(versions.getElevator());
        }

        if (!StringUtils.isEmpty(person.getFreshAirSystem())) {
            extract.setFreshAirSystem(person.getFreshAirSystem());
        } else {
            extract.setFreshAirSystem(versions.getFreshAirSystem());
        }

        if (!StringUtils.isEmpty(person.getHasHeating())) {
            extract.setHasHeating(person.getHasHeating());
        } else {
            extract.setHasHeating(versions.getHasHeating());
        }

        if (!StringUtils.isEmpty(person.getHeatingMethod())) {
            extract.setHeatingMethod(person.getHeatingMethod());
        } else {
            extract.setHeatingMethod(versions.getHeatingMethod());
        }

        if (!StringUtils.isEmpty(person.getHeatingRemark())) {
            extract.setHeatingRemark(person.getHeatingRemark());
        } else {
            extract.setHeatingRemark(versions.getHeatingRemark());
        }

        if (!StringUtils.isEmpty(person.getPrefabricatedBuildings())) {
            extract.setPrefabricatedBuildings(person.getPrefabricatedBuildings());
        } else {
            extract.setPrefabricatedBuildings(versions.getPrefabricatedBuildings());
        }

        if (!StringUtils.isEmpty(person.getPassiveRoom())) {
            extract.setPassiveRoom(person.getPassiveRoom());
        } else {
            extract.setPassiveRoom(versions.getPassiveRoom());
        }

        if (!StringUtils.isEmpty(person.getBuildInfo())) {
            extract.setBuildInfo(person.getBuildInfo());
        } else {
            extract.setBuildInfo(versions.getBuildInfo());
        }

        if (!StringUtils.isEmpty(person.getProjectEquipment())) {
            extract.setProjectEquipment(person.getProjectEquipment());
        } else {
            extract.setProjectEquipment(versions.getProjectEquipment());
        }

        if (!StringUtils.isEmpty(person.getProjectProgress())) {
            extract.setProjectProgress(person.getProjectProgress());
        } else {
            extract.setProjectProgress(versions.getProjectProgress());
        }

        if (!StringUtils.isEmpty(person.getLng())) {
            extract.setLng(person.getLng());
        } else {
            extract.setLng(versions.getLng());
        }

        if (!StringUtils.isEmpty(person.getLat())) {
            extract.setLat(person.getLat());
        } else {
            extract.setLat(versions.getLat());
        }

        if (!StringUtils.isEmpty(person.getGaoDeLng())) {
            extract.setGaoDeLng(person.getGaoDeLng());
        } else {
            extract.setGaoDeLng(versions.getGaoDeLng());
        }

        if (!StringUtils.isEmpty(person.getGaoDeLat())) {
            extract.setGaoDeLat(person.getGaoDeLat());
        } else {
            extract.setGaoDeLat(versions.getGaoDeLat());
        }

        if (!StringUtils.isEmpty(person.getSteelStructureRemark())) {
            extract.setSteelStructureRemark(person.getSteelStructureRemark());
        } else {
            extract.setSteelStructureRemark(versions.getSteelStructureRemark());
        }

        if (!StringUtils.isEmpty(person.getOtherExternalWallMaterials())) {
            extract.setOtherExternalWallMaterials(person.getOtherExternalWallMaterials());
        } else {
            extract.setOtherExternalWallMaterials(versions.getOtherExternalWallMaterials());
        }

        if (!StringUtils.isEmpty(person.getExternalWallMaterialsRemark())) {
            extract.setExternalWallMaterialsRemark(person.getExternalWallMaterialsRemark());
        } else {
            extract.setExternalWallMaterialsRemark(versions.getExternalWallMaterialsRemark());
        }

        if (!StringUtils.isEmpty(person.getElevatorRemark())) {
            extract.setElevatorRemark(person.getElevatorRemark());
        } else {
            extract.setElevatorRemark(versions.getElevatorRemark());
        }

        if (!StringUtils.isEmpty(person.getFreshAirSystemRemark())) {
            extract.setFreshAirSystemRemark(person.getFreshAirSystemRemark());
        } else {
            extract.setFreshAirSystemRemark(versions.getFreshAirSystemRemark());
        }

        if (!StringUtils.isEmpty(person.getOtherHeatingMethod())) {
            extract.setOtherHeatingMethod(person.getOtherHeatingMethod());
        } else {
            extract.setOtherHeatingMethod(versions.getOtherHeatingMethod());
        }

        return extract;
    }

    // 更新的比较逻辑，考虑version_rank可能是非数字的情况
    private static boolean isNewerVersion(ProjectVersions a, ProjectVersions b) {
        int timeCompare = b.getReleaseTime().compareTo(a.getReleaseTime());

        if (timeCompare != 0) {
            // 直接根据时间戳比较
            return timeCompare < 0;
        } else {
            // 时间戳相同，比较version_rank
            boolean isANum = isNumeric(a.getVersionRank());
            boolean isBNum = isNumeric(b.getVersionRank());

            if (isANum && isBNum) {
                // 都是数字时，倒序比较version_rank
                return Double.parseDouble(a.getVersionRank()) > Double.parseDouble(b.getVersionRank());
            } else if (!isANum && !isBNum) {
                // 都是非数字，认为一样新，保持原有顺序（此处逻辑需根据实际需求调整）
                return false; // 或者根据其他规则判定
            } else {
                // 一个数字一个非数字，非数字的认为更新
                return !isANum;
            }
        }
    }

    // 判断字符串是否为数字
    private static boolean isNumeric(String str) {
        try {
            Double.parseDouble(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

}
*/
